timeline = new Class ({
    timelinewatcherid: 'timelinewatcher',
    timelineeventslistid: 'timelineeventstablebody',
    from: 0,
    to: 0,
    currentstep: 0,
    step: 0,
    synchrostable: {},
    events: new Array(),
    running: false,

    initialize: function(options) {
        this.movetobegin();
    },

    addevent: function(code, at, repeatevery, evttarget) {
        if (at == 'random') {
            at = Math.floor(Math.random() * (this.to - this.from + 1) + this.from)
            athtml = at + "(rand)"
        }
        else
            athtml = at;

        if (repeatevery != 'random')
            repeatevery = Number(repeatevery);

        this.events[at] = {'code':code, 'at':Number(at), 'repeatevery':repeatevery, 'evttarget':evttarget};

        var tr = new Element('tr', {'id': 'ev_' + at});
        var td_at = new Element('td', {'styles': {
            'background-color': 'white',
            'text-align': 'center'
            }
        }).setHTML(athtml);
        var td_target = new Element('td', {'styles': {
            'background-color': 'white'
            }
        }).setHTML(evttarget);
        var td_code = new Element('td', {'styles': {
            'background-color': 'white'
            }
        }).setHTML(code);
        var td_rep = new Element('td', {'styles': {
            'background-color': 'white',
            'text-align': 'center'
            }
        }).setHTML(repeatevery);
        tr.adopt(td_at);
        tr.adopt(td_target);
        tr.adopt(td_code);
        tr.adopt(td_rep);

        $(this.timelineeventslistid).adopt(tr);
    },
    
    run: function() {
        this.running = true;
        for (idr in synchros)
            this.synchrostable[idr] = 0;
        this.t = setInterval("currentTimeline.engine('inc')", 1000);
    },
    
    stop: function() {
        this.running = false;

        document.getElementById(this.timelinewatcherid).value = this.currentstep;
        
        $$('#timelineeventstablebody td').setStyle('background-color', 'white');

        //currentTimeline.engine('first');
        clearInterval(this.t);
    },
    
    pause: function() {
        this.running = false;
        clearInterval(this.t);
    },
    
    movetobegin: function() {
        this.currentstep = this.from;
        document.getElementById(this.timelinewatcherid).value = this.currentstep;
        
        $$('#timelineeventstablebody td').setStyle('background-color', 'white');

        this.engine('first');
    },
    
    movetoend: function() {
        this.running = false;

        this.currentstep = this.to;
        document.getElementById(this.timelinewatcherid).value = this.currentstep;

        currentTimeline.engine('last');
    },
    
    onestepforward: function () {
        this.running = false;

        if (this.currentstep < this.to) {
            this.currentstep += this.step;
            document.getElementById(this.timelinewatcherid).value = this.currentstep;

            currentTimeline.engine('onestepinc');
        }
    },
    
    onestepbackward: function () {
        this.running = false;

        if (this.currentstep > this.from) {
            this.currentstep -= this.step;
            document.getElementById(this.timelinewatcherid).value = this.currentstep;

            currentTimeline.engine('onestepdec');
        }
    },
    
    engine: function(op) {
    
        switch(op) {
            case 'inc':
                this.currentstep += this.step;
            break;
            case 'dec':
                this.currentstep -= this.step;
            break;
            default:
                ;
            break;
        }
        
        if (this.currentstep >= this.to || this.currentstep < this.from)
            this.stop();

        document.getElementById(this.timelinewatcherid).value = this.currentstep;

        //l'evento avviene, ma non si vede cambiamento nel foglio per l'oggetto
        // che cambia nel caso di un assegnamento. il valore invece della unitbox
        // che utilizza la variabile cambiata dall'evento risente del cambiamento... chiaro no?
        if ($type(this.events[this.currentstep]) == 'object') {
            $$('#ev_' + this.currentstep + ' td').setStyle('background-color', 'yellow');

            eval("res = (" + this.events[this.currentstep].code + ");" + this.events[this.currentstep].evttarget + " = res; $('" + this.events[this.currentstep].evttarget + "').setHTML(res);");

            if (this.events[this.currentstep].repeatevery == undefined)
                this.events[this.currentstep] = null;
            else {
                if (this.events[this.currentstep].repeatevery == 'random')
                    newat = Number(Math.floor(Math.random() * (this.currentstep - this.from + 1) + this.from));
                else
                    newat = Number(this.events[this.currentstep].repeatevery) + this.currentstep;
                this.events[newat] = this.events[this.currentstep];
            }
        }
    
        for (idr in synchros) {
            
            if (this.running == false) {
                this.synchrorange(idr, op);
                continue;
            }
            
            if (this.synchrostable[idr] == synchros[idr]) {
                this.synchrorange(idr, op);
                this.synchrostable[idr] = 0;
            }
            else if (this.synchrostable[idr] == 0)
                this.synchrorange(idr, op);
            
            this.synchrostable[idr] += 1;
        }
    },
    
    synchrorange: function(idr, op) {
        currentUnitbox = unitboxes.ranges[idr];
        switch(op) {
            case 'inc':
                currentUnitbox.increment(true);
            break;
            case 'onestepinc':
                currentUnitbox.increment(true);
            break;
            case 'dec':
                currentUnitbox.decrement(true);
            break;
            case 'onestepdec':
                currentUnitbox.decrement(true);
            break;
            case 'first':
                currentUnitbox.move2first(true);
            break;
            case 'last':
                currentUnitbox.move2last(true);
            break;
        }
        
        // collect of all the function
        /*var functoexec = new Array();
        for (f in rangefunctionsmap[idr]) {
            idf = rangefunctionsmap[idr][f];
            functoexec.include(idf);
        }
        // execution of the functions
        functoexec.each(function(item, index) {
            document.getElementById(item).innerHTML = unitboxes.functions[item].callback();
            unitboxes.functions[item].bindfunction();
        });*/
    }
});